﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using EnvDTE;
using eAtlantida.Tools.Operations.GenerateOperations;

namespace eAtlantida.Tools.Operations
{
    public abstract class Operation
    {
        public abstract void Execute(State state);

        public event CommandLine.Message SendMessage;

        private static string Directory(ProjectItem project)
        {
            return project.Properties.Item("FullPath").Value.ToString();
        }

        protected void WriteMessage(string message, MessageType messageType)
        {
            SendMessage(message, messageType);
        }

        protected GenerateParameters GetGenerateParameters(IEnumerable<string> parameters)
        {
            var result = new GenerateParameters();

            if (!parameters.Any())
            {
                result.IsCreate = true;
                result.IsDelete = true;
                result.IsListing = true;
                result.IsSelect = true;
                result.IsUpdate = true;
                result.IsValidate = true;
                return result;
            }

            foreach (var parameter in parameters)
            {
                switch (parameter)
                {
                    case "c":
                    case "-c":
                        result.IsCreate = true;
                        break;
                    case "d":
                    case "-d":
                        result.IsDelete = true;
                        break;
                    case "l":
                    case "-l":
                        result.IsListing = true;
                        break;
                    case "s":
                    case "-s":
                        result.IsSelect = true;
                        break;
                    case "u":
                    case "-u":
                        result.IsUpdate = true;
                        break;
                    case "v":
                    case "-v":
                        result.IsValidate = true;
                        break;
                }
            }

            return result;
        }

        /// <summary>
        /// Gets the project.
        /// </summary>
        /// <param name="projectName">Name of the project.</param>
        private Project GetProject(string projectName)
        {
            if (Console.Dte == null)
                return null;

            var projects = Console.Dte.Solution.Projects;
            foreach (Project projectItem in projects)
            {
                if (projectItem.Name == projectName)
                {
                    return projectItem;
                }
            }
            return null;
        }

        /// <summary>
        /// Gets the folder.
        /// </summary>
        /// <param name="folderName">Name of the folder.</param>
        /// <param name="items">The items.</param>
        private ProjectItem GetFolder(string folderName, ProjectItems items)
        {
            foreach (ProjectItem folder in items)
            {
                if (folder.Name == folderName)
                {
                    return folder;
                }
            }
            return items.AddFolder(folderName);
        }

        /// <summary>
        /// Adds the procedure.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="name">The name.</param>
        /// <param name="body">The body.</param>
        /// <param name="extension">The extension.</param>
        public void AddFile(string path, string name, string body, string extension = ".cs")
        {
            var items = path.Split('/').ToArray();
            var project = GetProject(items[0]);
            if (project == null)
            {
                throw new ToolException("Project not found");
            }
            ProjectItem folder = null;
            var folderItems = project.ProjectItems;
            for (int index = 1; index < items.Length; index++)
            {
                var item = items[index];
                folder = GetFolder(item, folderItems);
                folderItems = folder.ProjectItems;
            }
            var filePath = Directory(folder);
            if (!File.Exists(filePath + name + extension))
            {
                using (TextWriter file = new StreamWriter(filePath + name + extension))
                {
                    file.Write(body);
                    file.Close();
                }
            }
            folder.ProjectItems.AddFromFile(filePath + name + extension);
        }

        public string SingleName(string name)
        {
            if (name.EndsWith("es"))
            {
                return name.Substring(0, name.Length - 2);
            }
            return name.Substring(0, name.Length - 1);
        }
    }
}